/**
 * XYF2120 训狗器数码屏驱动
 * Copyright (c) 2021 深圳市智辰科技有限公司
 * All rights reserved.
 */

#ifndef _XYF2120_H_
#define _XYF2120_H_

#include <stdint.h>
#include "nonos.h"


#define XYF2120_COM_COUNT 4
#define XYF2120_SEG_COUNT 8

/// SEG 的状态：0-关闭；1-常亮；2-慢闪；3-快闪
typedef enum {
	XYF2120_SM_OFF = 0,
	XYF2120_SM_ON = 1,
	XYF2120_SM_FLASH_SLOW = 2,
	XYF2120_SM_FLASH_FAST = 3,
	XYF2120_SM_MAX
} xyf2120_seg_mode_t;

// 8段数码可显示字符定义
typedef enum {
	XYF2120_8SEG_NULL,   // 空(不显示任何东西)
	XYF2120_8SEG_CHAR_0,
	XYF2120_8SEG_CHAR_1,
	XYF2120_8SEG_CHAR_2,
	XYF2120_8SEG_CHAR_3,
	XYF2120_8SEG_CHAR_4,
	XYF2120_8SEG_CHAR_5,
	XYF2120_8SEG_CHAR_6,
	XYF2120_8SEG_CHAR_7,
	XYF2120_8SEG_CHAR_8,
	XYF2120_8SEG_CHAR_9,
	XYF2120_8SEG_CHAR_A, // A
	XYF2120_8SEG_CHAR_b, // b
	XYF2120_8SEG_CHAR_C, // C
	XYF2120_8SEG_CHAR_c, // c
	XYF2120_8SEG_CHAR_d, // d
	XYF2120_8SEG_CHAR_E, // E
	XYF2120_8SEG_CHAR_F, // F
	XYF2120_8SEG_CHAR_G, // G
	XYF2120_8SEG_CHAR_H, // H
	XYF2120_8SEG_CHAR_h, // h
	XYF2120_8SEG_CHAR_J, // J
	XYF2120_8SEG_CHAR_L, // L
	XYF2120_8SEG_CHAR_n, // n
	XYF2120_8SEG_CHAR_o, // o
	XYF2120_8SEG_CHAR_p, // p
	XYF2120_8SEG_CHAR_q, // q
	XYF2120_8SEG_CHAR_r, // r
	XYF2120_8SEG_CHAR_t, // t
	XYF2120_8SEG_CHAR_U, // U
	XYF2120_8SEG_CHAR_u, // u
	XYF2120_8SEG_CHAR_y, // y
	XYF2120_8SEG_CHAR_MINUS, // -
	XYF2120_8SEG_CHAR_UNDERLINE, // _
	XYF2120_8SEG_CHAR_MAX,
} xyf2120_8seg_char_t;

/// 电池状态
typedef enum {
	XYF2120_BAT_EMPTY,	// 电量耗尽: 红灯慢闪
	XYF2120_BAT_LOW,	// 低电量告警: 红灯常亮，电量1格慢闪
	XYF2120_BAT_MEDIUM, // 电量中等: 白灯常亮，电量2格
	XYF2120_BAT_FULL,	// 电量满: 白灯常亮，电量3格
	XYF2120_BAT_TEST,	// 屏幕测试: 红灯慢闪，白灯常亮，电量3格
	XYF2120_BAT_MAX
} xyf2120_bat_state_t;

/// 射频信号状态
typedef enum {
	XYF2120_RF_LOSS,	// 无信号: 红灯慢闪
	XYF2120_RF_LOW,		// 信号弱告警: 红灯常亮，信号1格慢闪
	XYF2120_RF_MEDIUM,	// 信号中等: 白灯常亮，信号2格
	XYF2120_RF_FULL,	// 信号满格: 白灯常亮，信号3格
	XYF2120_RF_TEST,	// 屏幕测试: 红灯慢闪，白灯常亮，信号3格
	XYF2120_RF_MAX
} xyf2120_rf_state_t;


#pragma pack(push, 1)

// 显存结构
// 参见《数码管 XYF2120-A1.pdf》
typedef union {
	// 总共 8 个字节，COM0~COM3 所控制的图形每个占 2 个字节
	uint8_t bytes[8];
	// 每2bits表示一个 SEG 的状态：0-关闭；1-常亮；2-慢闪；3-快闪
	// 注意：struct 是高位在前的！
	struct {
		// COM0
		uint8_t SHAKE    :2; // 振动指示
		uint8_t N1G      :2;
		uint8_t N1F      :2;
		uint8_t N1E      :2;
		uint8_t N1D      :2;
		uint8_t N1C      :2;
		uint8_t N1B      :2;
		uint8_t N1A      :2;

		// COM1
		uint8_t STATIC   :2; // 电击指示
		uint8_t N2G      :2;
		uint8_t N2F      :2;
		uint8_t N2E      :2;
		uint8_t N2D      :2;
		uint8_t N2C      :2;
		uint8_t N2B      :2;
		uint8_t N2A      :2;

		// COM2
		uint8_t _res1:6;
		uint8_t BAT_HIGH :2;	// 电量：高
		uint8_t BAT_MED  :2;	// 电量：中
		uint8_t BAT_LOW  :2;	// 电量：低
		uint8_t BAT_WARN :2;	// 电量告警：红灯
		uint8_t BAT_OK   :2; // 电量正常：白灯

		// COM3
		uint8_t _res2:2;
		uint8_t BARK     :2; // 自动止吠指示
		uint8_t VOICE    :2;	// 声音指示
		uint8_t RF_HIGH  :2;	// 遥控信号：高
		uint8_t RF_MED   :2;	// 遥控信号：中
		uint8_t RF_LOW   :2;	// 遥控信号：低
		uint8_t RF_WARN  :2;	// 遥控信号告警：红灯
		uint8_t RF_OK    :2;	// 遥控信号正常：白灯
	} st;
} xyf2120_ram_t;

#pragma pack(pop)


/// 设备驱动数据结构
typedef struct {
	// 引脚控制接口
	FUNC_GPIO_Switch coms[XYF2120_COM_COUNT];
	FUNC_GPIO_Switch segs[XYF2120_SEG_COUNT];

	// 慢闪速度(亮灭保持时间, ms)
	uint16_t flashIntervalSlow;
	// 快闪速度(亮灭保持时间, ms)
	uint16_t flashIntervalFast;
	// 慢闪当前周期还剩余的时间(ms)，如果剩余时间不足，则状态反转，重新计时
	uint32_t flashTimeStampSlow;
	// 慢闪当前周期还剩余的时间(ms)，如果剩余时间不足，则状态反转，重新计时
	uint32_t flashTimeStampFast;
	// 当前是慢闪的哪一个状态: 0-表示当前是“灭”；1-表示当前是“亮”
	uint8_t flashStateSlow;
	// 当前是快闪的哪一个状态: 0-表示当前是“灭”；1-表示当前是“亮”
	uint8_t flashStateFast;

	// 是否启用(不启用时驱动不动作)
	uint8_t enable;

	// 因各个SEG对于各个COM是复用的，必须利用视觉暂存原理进行快速扫描(必须大于24KHz)各个COM，从而看起来显示的是一个整体
	// 此字段表示当前刷新到哪一个COM段了: COM0~COM3
	uint8_t ccom;

	// 显存
	xyf2120_ram_t ram;
} driver_xyf2120_t;


// 初始化
void xyf2120_init(driver_xyf2120_t* dev);
// 打开或关闭显示
void xyf2120_enable(driver_xyf2120_t* dev, uint8_t enable);
// 清除显示
void xyf2120_clear(driver_xyf2120_t* dev);
// 直接设置显存
void xyf2120_display(driver_xyf2120_t* dev, xyf2120_ram_t *ram);
// 定时刷新
_RAMCODE_ void _xyf2120_timing_refresh(driver_xyf2120_t* dev);

// 显示指定内容
// @param num 数字0~99
// @param numMode 数字显示模式
// @param shakeMode 振动开关状态指示
// @param staticMode 电击开关状态指示
// @param voiceMode 声音开关状态指示
// @param barkMode 止吠开关状态指示
// @param batState 电池状态
// @param rfState 遥控信号状态
void xyf2120_set(driver_xyf2120_t* dev,
	uint8_t level,
	xyf2120_seg_mode_t levelMode,
	xyf2120_seg_mode_t shakeMode,
	xyf2120_seg_mode_t staticMode,
	xyf2120_seg_mode_t voiceMode,
	xyf2120_seg_mode_t barkMode,
	xyf2120_bat_state_t batState,
	xyf2120_rf_state_t rfState
);

// 显存操作：清除显存
void xyf2120_ram_clear(xyf2120_ram_t *ram);

// 显存操作：设置8段数码显示字符
void xyf2120_ram_set_char1(xyf2120_ram_t *ram, xyf2120_8seg_char_t ch, xyf2120_seg_mode_t mode);
void xyf2120_ram_set_char2(xyf2120_ram_t *ram, xyf2120_8seg_char_t ch, xyf2120_seg_mode_t mode);

// 显存操作：设置电击级别0~99
void xyf2120_ram_set_static_level(xyf2120_ram_t *ram, uint8_t level, xyf2120_seg_mode_t mode);
// 显存操作：设置振动开关状态指示
void xyf2120_ram_set_shake(xyf2120_ram_t *ram, xyf2120_seg_mode_t mode);
// 显存操作：设置电击开关状态指示
void xyf2120_ram_set_static(xyf2120_ram_t *ram, xyf2120_seg_mode_t mode);
// 显存操作：设置声音开关状态指示
void xyf2120_ram_set_voice(xyf2120_ram_t *ram, xyf2120_seg_mode_t mode);
// 显存操作：设置止吠开关状态指示
void xyf2120_ram_set_bark(xyf2120_ram_t *ram, xyf2120_seg_mode_t mode);
// 显存操作：设置电池状态
void xyf2120_ram_set_bat_state(xyf2120_ram_t *ram, xyf2120_bat_state_t state);
// 显存操作：设置遥控信号状态
void xyf2120_ram_set_rf_state(xyf2120_ram_t *ram, xyf2120_rf_state_t state);

// 测试
void xyf2120_test(driver_xyf2120_t* dev);


#endif // _XYF2120_H_
